package com.service.impl;

import com.cache.impl.LxfCacheService;
import com.core.dto.FileUploadDTO;
import com.core.dto.GoodDTO;
import com.core.model.UploadImage;
import com.core.model.lxf.FileUpload;
import com.core.model.lxf.Good;
import com.core.model.lxf.GoodType;
import com.core.model.lxf.SecKillGoods;
import com.core.model.user.UserInfo;
import com.core.shared.ImageUtils;
import com.core.shared.TraceUtil;
import com.core.shared.WebUtil;
import com.dao.LxfDao;
import com.service.LxfService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: xianfei
 * Date: 15-8-12
 * Time: 上午10:20
 * To change this template use File | Settings | File Templates.
 */
@Service("xfService")
@Transactional
public class XfServiceImpl implements LxfService {

    @Autowired
    private LxfDao lxfDao;

    @Autowired
    @Lazy   //避免跟lxfCacheService之间的循环依赖
    private LxfCacheService lxfCacheService;

    @Override
    @Transactional
    public void add(GoodDTO goodDTO) {
        Good good = new Good("lxfname", "23");
        lxfDao.saveOrUpdate(good);
        int a = 0;
        if (a == 0) {
            throw new RuntimeException();
        }
    }

    @Override
    @Transactional
    public void saveOrUpdateFile(FileUploadDTO fileUploadDTO) {
        FileUpload file = FileUploadDTO.toFileUpload(fileUploadDTO);
        lxfDao.saveOrUpdate(file);
    }

    @Override
    @Transactional
    public void upload(MultipartFile file) {
//        ImageUtil.upload(file);
        UploadImage uploadImage = ImageUtils.multipartFileToUploadImage(file);
        lxfDao.saveOrUpdate(uploadImage);
    }

    @Override
    @Transactional
    public void download(HttpServletResponse response) {
//        ImageUtil.download(response);
        UploadImage uploadImage = lxfDao.findByGuid(UploadImage.class, "b9ba2ca1-1b59-407d-af74-e18b99799356");
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/x-download");
        response.setHeader("Content-Disposition", "attachment;fileName=" + uploadImage.getName() + ".jpg");
        try {
            InputStream is = new ByteArrayInputStream(uploadImage.getContents());
            BufferedInputStream bis = new BufferedInputStream(is);
            BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
            byte[] b = new byte[1024];
            int i;
            while ((i = bis.read(b)) > 0) {
                bos.write(b, 0, i);
            }
            bis.close();
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public byte[] showImageByGuid(String guid) {
        UploadImage uploadImage = lxfDao.findImageByGuid(guid);
        return uploadImage.getContents();
    }

    @Override
//    @Scheduled(cron = "0/1 * * * * ?")
    public void autoSchedule() {
        System.out.println("每秒一次***");
    }

    @Override
    @Transactional
    public List<GoodDTO> allStudent() {
        List<Good> goods = lxfDao.findAllStudent();
        List<GoodDTO> goodDTOs = GoodDTO.toDTOs(goods);
        return goodDTOs;
    }

    @Override
    @Transactional
    public Map<String, Object> saveGood(GoodDTO goodDTO) {
        Map<String, Object> map = new HashMap<>();
        try {
            Good good = GoodDTO.toGood(goodDTO);
            lxfDao.saveOrUpdate(good);
            map.put("result", true);
            map.put("data", good.guid());
        } catch (Exception e) {
            map.put("result", false);
        }
        return map;
    }

    @Override
    @Transactional
    public Map<String, Object> delGood(String goodGuid) {
        Map<String, Object> map = new HashMap<>();
        try {
            Good good = lxfDao.findByGuid(Good.class, goodGuid);
            lxfCacheService.invalidate(goodGuid);
            lxfDao.deleteObject(good);
            map.put("result", true);
        } catch (Exception e) {
            map.put("result", false);
        }
        return map;
    }

    @Override
    @Transactional
    public Map<String, Object> updateGood(GoodDTO goodDTO) {
        Map<String, Object> map = new HashMap<>();
        try {
            Good good = lxfDao.findByGuid(Good.class, goodDTO.getGuid());
            good.update(goodDTO);
            lxfCacheService.invalidate(goodDTO.getGuid());
            map.put("result", true);
        } catch (Exception e) {
            map.put("result", false);
        }
        return map;
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public UserInfo findUserInfoByUserGuid(String userInfoGuid) {
        UserInfo userInfo = lxfDao.findUserInfoByUserGuid(userInfoGuid);
        return userInfo;
    }

    @Override
    @Transactional
    public void addGood() {
        lxfDao.addGood();
    }

    @Override
    public GoodType findGoodType() {
        System.out.println("---------traceId:" + TraceUtil.getRequestTraceId(WebUtil.getRequest()));
        GoodType goodType = lxfDao.findGoodTypeByGuid();
        System.out.println("***********size: " + goodType.goods().size());
//        System.out.println("************good name = " + goodType.goods().get(2).name());
        return goodType;
    }

    @Override
    public void aopLearn(HttpServletResponse response, HttpServletRequest request) {
        System.out.println("学习AOP");
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public SecKillGoods findById(String id) {
        return lxfDao.findById(id);
    }

    @Override
    public int reduceStock(String id, Integer remainNum) {
        return lxfDao.reduceStock(id, remainNum);
    }

    @Override
    public void generateOrder(String consumer, String goodsId, Integer num) {
        lxfDao.generateOrder(consumer, goodsId, num);
    }

    @Override
    public void saveSecKillGoods(SecKillGoods secKillGoods) {
        lxfDao.saveOrUpdate(secKillGoods);
    }

}
